package com.task.core.service.impl;

import java.util.*;
import java.util.concurrent.TimeUnit;
import javax.annotation.Resource;

import com.task.common.constant.ErrorCodeConstants;
import com.task.common.enums.DataFileTypeEnum;
import com.task.common.utils.TableNameUtils;
import com.task.core.domain.DataOperationInfo;
import com.task.core.dto.request.MissionDataDetailRequestDTO;
import com.task.core.dto.request.info.HistoryDataDetailInfo;
import com.task.core.dto.response.MissionHistoryDetailResposeDTO;
import com.task.core.vo.resp.DataContentDetailRespVo;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import cn.hutool.json.JSONArray;

import com.alibaba.fastjson2.JSON;
import com.github.pagehelper.PageHelper;
import com.task.common.annotation.DataScope;
import com.task.common.core.redis.RedisCache;
import com.task.common.exception.ServiceException;
import com.task.common.utils.SecurityUtils;
import com.task.common.utils.StringUtils;
import com.task.common.utils.SystemFunctionUtil;
import com.task.common.utils.date.DateConstants;
import com.task.common.utils.date.DateUtil;
import com.task.core.domain.DataSendHistoryInfo;
import com.task.core.domain.MissionSendHistoryInfo;
import com.task.core.dto.request.DataSendDetailRequestDTO;
import com.task.core.dto.request.MissionSendDetailRequestDTO;
import com.task.core.dto.request.info.HistoryDataSearchInfo;
import com.task.core.mapper.SendHistoryMapper;
import com.task.core.service.SendHistoryService;

/**
 * @author 迪迦.
 * @date 2024/12/27 10:34
 */
@Service
public class SendHistoryServiceImpl implements SendHistoryService {

  @Resource
  private SendHistoryMapper sendHistoryMapper;

  @Resource
  private RedisCache redisCache;

  @Override
  public List<String> getIndexTableNameByPrefix(String historyDataGetIndex) {
    return sendHistoryMapper.getIndexTableNameByPrefix(historyDataGetIndex);
  }

  @Override
  @DataScope(deptAlias = "dept", userAlias = "su")
  public List<DataSendHistoryInfo> getDataSendDetailHistory(DataSendDetailRequestDTO request) {
    //先查询当前查看用户是不是管理员,如果不是就需要先查询属于哪个部门,部门下面能看到哪些数据
    List<String> missionCodes = getCanSeeMissionCodes(request);
    Date now = new Date();
    if (StringUtils.isEmpty(request.getStartTime())) {
      request.setStartTime(DateUtil.dateToStr(now, DateConstants.DATE_FORMAT_START));
    }
    if (StringUtils.isEmpty(request.getEndTime())) {
      request.setEndTime(DateUtil.dateToStr(now, DateConstants.DATE_FORMAT_END));
    }
    List<HistoryDataSearchInfo> searchTableList = new ArrayList<>();
    if (!StringUtils.isEmpty(request.getId())) {
      if (request.getId().length() < 10) {
        throw new ServiceException("id格式错误");
      }
      String substring = request.getId().substring(0, 6);
      String tn = SystemFunctionUtil.getHistoryTableNameByTime(substring, SystemFunctionUtil.HISTORY_DATA_GET_DETAIL);
      searchTableList.add(new HistoryDataSearchInfo(tn, request.getStartTime(), request.getEndTime()));
    } else {
      searchTableList = getSearchTableList(SystemFunctionUtil.HISTORY_DATA_GET_DETAIL, request.getStartTime(),
          request.getEndTime());
    }
    PageHelper.startPage(request.getPageNum(), request.getPageSize());
    if(CollectionUtils.isEmpty(searchTableList)) {
      throw new ServiceException("时间段内没有数据");
    }
    return sendHistoryMapper.getDataSendDetailHistory(request, missionCodes, searchTableList);
  }

  public List<HistoryDataSearchInfo> getSearchTableList(String tablePre, String startTime, String endTime) {
    List<String> tables = sendHistoryMapper.getIndexTableNameByPrefix(tablePre);
    if (CollectionUtils.isEmpty(tables)) {
      throw new ServiceException("数据库异常,缺失数据表");
    }
    Date startDate = DateUtil.strToDate(startTime);
    Date endDate = DateUtil.strToDate(endTime);
    List<HistoryDataSearchInfo> historyDataSearchInfos = new ArrayList<>();
    int startY = Integer.parseInt(Objects.requireNonNull(DateUtil.dateToStr(startDate, DateConstants.DATE_FORMAT_YEAR)));
    int startM = Integer.parseInt(DateUtil.dateToStr(startDate, DateConstants.DATE_FORMAT_MONTH_ONLY));

    Integer endY = Integer.parseInt(Objects.requireNonNull(DateUtil.dateToStr(endDate, DateConstants.DATE_FORMAT_YEAR)));
    int endM = Integer.parseInt(DateUtil.dateToStr(endDate, DateConstants.DATE_FORMAT_MONTH_ONLY));

    int loopTime = 0;
    while (true) {
      String tableName = SystemFunctionUtil.getHistoryTableNameByTime(getTableSuf(startY, startM), tablePre);
      if ((startY + "-" + startM).equals((endY + "-" + endM))) {
        //本月,应该结束
        if (loopTime == 0) {
          //没有跨月,需要开始和结束时间
          if (tables.contains(tableName)) {
            historyDataSearchInfos.add(
                new HistoryDataSearchInfo(
                    tableName,
                    DateUtil.dateToStr(startDate, DateConstants.DATE_FORMAT_START),
                    DateUtil.dateToStr(endDate, DateConstants.DATE_FORMAT_END))
            );
          }
        } else {
          //跨月的情况只需要结束时间
          if (tables.contains(tableName)) {
            historyDataSearchInfos.add(new HistoryDataSearchInfo(tableName, null, DateUtil.dateToStr(endDate, DateConstants.DATE_FORMAT_END)));
          }
        }
        break;
      } else {
        //非本月
        if (loopTime == 0) {
          //跨月中的第一月只需要开始时间
          if (tables.contains(tableName)) {
            historyDataSearchInfos.add(new HistoryDataSearchInfo(tableName, DateUtil.dateToStr(startDate, DateConstants.DATE_FORMAT_START), null));
          }

        } else {
          //跨月中的中间月份只需要表名,不需要时间,直接查询所有
          if (tables.contains(tableName)) {
            historyDataSearchInfos.add(new HistoryDataSearchInfo(tableName, null, null));
          }
        }
      }
      //处理下一次的年月值
      startM += 1;
      if (startM == 13) {
        startM = 1;
        startY += 1;
      }
      loopTime++;
    }
    return historyDataSearchInfos;
  }

  private String getTableSuf(Integer startY, Integer startM) {
    String startMStr = startM + "";
    if (startM < 10) {
      startMStr = "0" + startM;
    }
    return startY + startMStr;
  }


  @DataScope(deptAlias = "dept", userAlias = "su")
  private List<String> getCanSeeMissionCodes(DataSendDetailRequestDTO request) {
    //if (SecurityUtils.isAdmin()) {
    //  return null;
    //}
    //List<String> missionCodes = missionService.getMissionForHistory();
    List<String> missionCodes = sendHistoryMapper.getDataForHistory(request);
//    if (CollectionUtils.isEmpty(missionCodes)) {
//      throw new ServiceException("没有任务查看历史");
//    }
    return missionCodes;
  }

  @Override
  @DataScope(deptAlias = "dept", userAlias = "su")
  public List<MissionSendHistoryInfo> getMissionSendDetailHistory(MissionSendDetailRequestDTO request) {
    //先查询当前查看用户是不是管理员,如果不是就需要先查询属于哪个部门,部门下面能看到哪些数据
    List<String> missionCodes = getCanSeeMissionCodes(request);

    Date now = new Date();
    if (StringUtils.isEmpty(request.getStartTime())) {
      request.setStartTime(DateUtil.dateToStr(now, DateConstants.DATE_FORMAT_START));
    }
    if (StringUtils.isEmpty(request.getEndTime())) {
      request.setEndTime(DateUtil.dateToStr(now, DateConstants.DATE_FORMAT_END));
    }
    List<HistoryDataSearchInfo> searchTableList = new ArrayList<>();
    if (!StringUtils.isEmpty(request.getId())) {
      if (request.getId().length() < 10) {
        throw new ServiceException("id格式错误");
      }
      String substring = request.getId().substring(0, 6);
      String tn = SystemFunctionUtil.getHistoryTableNameByTime(substring, SystemFunctionUtil.HISTORY_MISSION_GET_DETAIL);
      searchTableList.add(new HistoryDataSearchInfo(tn, request.getStartTime(), request.getEndTime()));
    } else {
      searchTableList = getSearchTableList(SystemFunctionUtil.HISTORY_MISSION_GET_DETAIL, request.getStartTime(),
          request.getEndTime());
    }
    PageHelper.startPage(request.getPageNum(), request.getPageSize());
    if(CollectionUtils.isEmpty(searchTableList)) {
      throw new ServiceException("时间段内没有数据");
    }
    List<MissionSendHistoryInfo> missionSendDetailHistory = sendHistoryMapper.getMissionSendDetailHistory(missionCodes, searchTableList, request);
    for (MissionSendHistoryInfo missionSendHistoryInfo : missionSendDetailHistory) {
      //获取dataId记录的表名
      List<String> tableName = SystemFunctionUtil.getHistoryTablesNameByTime(missionSendHistoryInfo.getGmtCreate(), SystemFunctionUtil.HISTORY_DATA_GET_DETAIL);
      missionSendHistoryInfo.setDataSendInfo(sendHistoryMapper.getDataSendInfosByMissionCode(missionSendHistoryInfo.getCode(), tableName));
      if(!ObjectUtils.isEmpty(missionSendHistoryInfo.getDataIdString())){
        String[] split = missionSendHistoryInfo.getDataIdString().split(",");
        List<String> dataIds = new ArrayList<>();
        for (String dataId : split) {
          dataIds.add(dataId);
        }
        missionSendHistoryInfo.setDataIdString(null);
        missionSendHistoryInfo.setDataIds(dataIds);
      }
    }
    return missionSendDetailHistory;
  }

  @Override
  public List<MissionHistoryDetailResposeDTO> getMissionSendHistoryByTimeType(List<HistoryDataSearchInfo> searchInfo, String missionCode) {
    return sendHistoryMapper.getMissionSendHistoryByTimeType(searchInfo, missionCode);
  }

  @Override
  public String getHistoryIdByNameAndTime(String dateFormat, String dateFormatYmdHms, String tablePre) {
    if (!getInfoByName(tablePre, dateFormat, 1)) {
      throw new ServiceException("缓存服务错误,请联系管理员处理");
    }
    StringBuilder incrementValue = new StringBuilder(redisCache.redisTemplate.opsForValue().increment(tablePre + dateFormat).toString());
    int lackLength = 9 - incrementValue.length();
    for (int i = 0; i < lackLength; i++) {
      incrementValue.insert(0, "0");
    }
    return incrementValue.insert(0, dateFormatYmdHms).toString();
  }

  private boolean getInfoByName(String tablePre, String dateFormat, int times) {
    if(redisCache.hasKey(tablePre + dateFormat)) {
      return true;
    }
    if (times > 30) {
      return false;
    }
    boolean setData = false;
    boolean setId = false;
    try {
      Boolean ifAbsent = redisCache.redisTemplate.opsForValue().setIfAbsent(tablePre + dateFormat + "_getId", 1, 2, TimeUnit.MINUTES);
      setData = true;
      if(Boolean.FALSE.equals(ifAbsent)) {
        Thread.sleep(1000);
        times += 1;
        return getInfoByName(tablePre, dateFormat, times);
      }
      Integer id;
      //按不同的表前缀查询最大id
      switch (tablePre) {
        case SystemFunctionUtil.TABLE_PREFIX:
          id = sendHistoryMapper.getDataContentMaxId(SystemFunctionUtil.getDataTables(SystemFunctionUtil.TABLE_PREFIX));
          break;
        case SystemFunctionUtil.REFERER_TABLE_PREFIX:
          id = sendHistoryMapper.getDataContentMaxId(SystemFunctionUtil.getDataTables(SystemFunctionUtil.REFERER_TABLE_PREFIX));
          break;
        case SystemFunctionUtil.HISTORY_DATA_GET_DETAIL:
        case SystemFunctionUtil.HISTORY_MISSION_GET_DETAIL:
          id = sendHistoryMapper.getSendDetailMaxId(tablePre + dateFormat);
          break;
        default:
          return false;
      }
      //setId
      if (ObjectUtils.isEmpty(id)) {
        id = 1;
      }
      redisCache.setCacheObject(tablePre + dateFormat, id);
      setId = true;
    }catch (Exception e) {
      e.printStackTrace();
    }finally {
      if (setData) {
        redisCache.deleteObject(tablePre + dateFormat + "_getId");
      }
    }
    return setId;
  }

  @Override
  public DataSendHistoryInfo getDataSendDetailById(DataSendDetailRequestDTO request) {
    return null;
  }

  /**
   * 更新任务历史详情
   *
   * @param searchTableList
   */
  @Override
  public void updateMissionHistoryaDetailIsDisplay(List<HistoryDataSearchInfo> searchTableList) {
    sendHistoryMapper.updateMissionHistoryaDetailIsDisplay(searchTableList);
  }

  @Override
  public List<DataContentDetailRespVo> getMissionDataDetail(MissionDataDetailRequestDTO request) {

    if (StringUtils.isEmpty(request.getId())) {
      throw  new ServiceException(ErrorCodeConstants.MISSION_SEND_ID_IS_EMPTY.getMsg());
    }
    if (request.getId().length() < 10) {
      throw new ServiceException(ErrorCodeConstants.ID_FORMAT_ERROR.getMsg());
    }
    String substring = request.getId().substring(0, 6);
    String tableName = SystemFunctionUtil.getHistoryTableNameByTime(substring, SystemFunctionUtil.HISTORY_MISSION_GET_DETAIL);
    String dataIds =sendHistoryMapper.getDataIdsByCode(request.getCode(), tableName);
    if (!ObjectUtils.isEmpty(dataIds)) {
      String[] split = dataIds.split(",");
      Map<String, List<Long>> dataMap = new HashMap<>();
      for (String dataId : split) {
       String dataTableName = SystemFunctionUtil.getDistributeTableNameById (dataId, DataFileTypeEnum.DATA.name(),false) ;
       if(dataMap.get(dataTableName) == null){
         List<Long> list = new ArrayList<>();
         list.add(Long.valueOf(dataId));
         dataMap.put(dataTableName,list);
       }else {
         dataMap.get(dataTableName).add(Long.valueOf(dataId));
       }
      }
      List<HistoryDataDetailInfo> list = new ArrayList<HistoryDataDetailInfo>();
      for (Map.Entry<String, List<Long>> entry : dataMap.entrySet()) {
        list.add(new HistoryDataDetailInfo(entry.getKey(), entry.getValue()));
      }

      List<DataOperationInfo> dataContent = sendHistoryMapper.getDataContent(list);
      List<DataContentDetailRespVo> result = new ArrayList<>();
      dataContent.forEach(dataOperationInfo -> {
        result.add(new DataContentDetailRespVo(dataOperationInfo.getId(),dataOperationInfo.getDataContent()));
      });
      return result;

    }

    return Collections.emptyList();
  }



  //private List<HistoryDataSearchInfo> getTableNameByTimeType(String timeType, String tablePre, Date nowDate, WeekEnum week) {
  //  List<HistoryDataSearchInfo> historyDataSearchInfos = new ArrayList<>();
  //  if (MissionSearchTimeEnum.TODAY.name().equals(timeType)) {
  //    //当天
  //    String dateFormat = DateUtil.dateToStr(nowDate, DateConstants.DATE_FORMAT_YM);
  //    String tableName = SystemFunctionUtil.getHistoryTableNameByTime(dateFormat, tablePre);
  //    historyDataSearchInfos.add(new HistoryDataSearchInfo(tableName, DateUtil.dateToStr(nowDate, DateConstants.DATE_FORMAT_START),
  //        DateUtil.dateToStr(nowDate, DateConstants.DATE_FORMAT_END)));
  //  } else if (MissionSearchTimeEnum.YESTERDAY.name().equals(timeType)) {
  //    //昨天
  //    Date searchDate = DateUtil.addDay(nowDate, -1);
  //    String dateFormat = DateUtil.dateToStr(searchDate, DateConstants.DATE_FORMAT_YM);
  //    String tableName = SystemFunctionUtil.getHistoryTableNameByTime(dateFormat, tablePre);
  //    historyDataSearchInfos.add(new HistoryDataSearchInfo(tableName, DateUtil.dateToStr(searchDate, DateConstants.DATE_FORMAT_START),
  //        DateUtil.dateToStr(searchDate, DateConstants.DATE_FORMAT_END)));
  //  } else if (MissionSearchTimeEnum.THIS_WEEK.name().equals(timeType)) {
  //    return getSearchTableList(tablePre, DateUtil.addDay(nowDate, -(week.getInfo() - 1)), nowDate);
  //  } else if (MissionSearchTimeEnum.LAST_2_DAYS.name().equals(timeType)) {
  //    return getSearchTableList(tablePre, DateUtil.addDay(nowDate, -2), nowDate);
  //  } else if (MissionSearchTimeEnum.LAST_3_DAYS.name().equals(timeType)) {
  //    return getSearchTableList(tablePre, DateUtil.addDay(nowDate, -(week.getInfo() - 1)), nowDate);
  //  } else if (MissionSearchTimeEnum.LAST_7_DAYS.name().equals(timeType)) {
  //    return getSearchTableList(tablePre, DateUtil.addDay(nowDate, -(week.getInfo() - 1)), nowDate);
  //  } else if (MissionSearchTimeEnum.LAST_14_DAYS.name().equals(timeType)) {
  //    return getSearchTableList(tablePre, DateUtil.addDay(nowDate, -(week.getInfo() - 1)), nowDate);
  //  } else if (MissionSearchTimeEnum.THIS_MONTH.name().equals(timeType)) {
  //    return getSearchTableList(tablePre, DateUtil.addDay(nowDate, -(week.getInfo() - 1)), nowDate);
  //  } else if (MissionSearchTimeEnum.LAST_MONTH.name().equals(timeType)) {
  //    return getSearchTableList(tablePre, DateUtil.addDay(nowDate, -(week.getInfo() - 1)), nowDate);
  //  } else if (MissionSearchTimeEnum.THIS_YEAR.name().equals(timeType)) {
  //    return getSearchTableList(tablePre, DateUtil.addDay(nowDate, -(week.getInfo() - 1)), nowDate);
  //  } else if (MissionSearchTimeEnum.LAST_YEAR.name().equals(timeType)) {
  //    return getSearchTableList(tablePre, DateUtil.addDay(nowDate, -(week.getInfo() - 1)), nowDate);
  //  } else if (MissionSearchTimeEnum.ALL_TIME.name().equals(timeType)) {
  //    return getSearchTableList(tablePre, DateUtil.addDay(nowDate, -(week.getInfo() - 1)), nowDate);
  //  }
  //
  //  return historyDataSearchInfos;
  //}

  @DataScope(deptAlias = "dept", userAlias = "su")
  private List<String> getCanSeeMissionCodes(MissionSendDetailRequestDTO request) {
    List<String> missionCodes = sendHistoryMapper.getMissionForHistory(request);
//    if (CollectionUtils.isEmpty(missionCodes)) {
//      throw new ServiceException("没有任务查看历史");
//    }
    return missionCodes;
  }
}
